package com.ai.util;


import java.util.Arrays;

/**
 * 数字进制相互转换
 *
 * @author le.li
 */
public class NumberUtil {
    private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};


    /**
     * 方法二：
     * byte[] to hex string
     *
     * @param bytes
     * @return
     */
    public static String bytesToHexFun2(byte[] bytes) {
        char[] buf = new char[bytes.length * 2];
        int index = 0;
        for (byte b : bytes) { // 利用位运算进行转换，可以看作方法一的变种
            buf[index++] = HEX_CHAR[b >>> 4 & 0xf];
            buf[index++] = HEX_CHAR[b & 0xf];
        }

        return new String(buf);
    }


    /**
     * 4个byte转为数字
     * 丢进去一个byte数组，从第offset开始取4条数据
     *
     * @param ary
     * @param offset
     * @return
     */
    public static int bytesToInt(byte[] ary, int offset) {
        int value;
        value = (int) ((ary[offset] & 0xFF << 24)
                | ((ary[offset + 1] & 0xFF) << 16)
                | ((ary[offset + 2] & 0xFF) << 8)
                | ((ary[offset + 3] & 0xFF)));
        return value;
    }


    /**
     * 两个byte转为int
     *
     * @param high
     * @param low
     * @return
     */
    public static int mergeByte2Hex(byte high, byte low) {
        return (int) ((high & 0xff) << 8 | (low & 0xff));
    }


    public static int byte2Int(byte[] b) {
        int intValue = 0;
        for (int i = 0; i < b.length; i++) {
            intValue += (b[i] & 0xFF) << (8 * (3 - i));
        }
        return intValue;
    }

    /**
     * 数字转为4个byte
     *
     * @param i
     * @return
     */
    public static byte[] intToByteArray(int i) {
        byte[] result = new byte[4];
        result[0] = (byte) ((i >> 24) & 0xFF);
        result[1] = (byte) ((i >> 16) & 0xFF);
        result[2] = (byte) ((i >> 8) & 0xFF);
        result[3] = (byte) (i & 0xFF);
        return result;
    }

    /**
     * 二进制转十进制
     *
     * @param number
     * @return
     */
    public static int binary2Decimal(String number) {
        return scale2Decimal(number, 2);
    }

    /**
     * 其他进制转十进制
     *
     * @param number
     * @return
     */
    public static int scale2Decimal(String number, int scale) {
        number = number.replaceAll(" ", "");
        checkNumber(number);
        if (2 > scale || scale > 32) {
            throw new IllegalArgumentException("scale is not in range");
        }
        // 不同其他进制转十进制,修改这里即可
        int total = 0;
        String[] ch = number.split("");
        int chLength = ch.length;
        for (int i = 0; i < chLength; i++) {
            total += Integer.valueOf(ch[i]) * Math.pow(scale, chLength - 1 - i);
        }
        return total;

    }

    /**
     * 十进制转二进制
     *
     * @param number
     * @return
     */
    public static String decimal2Binary(int number) {
        return decimal2Scale(number, 2, 0);
    }


    /**
     * 十进制转二进制
     *
     * @param number
     * @return
     */
    public static String decimal2Binary(int number, int digit) {
        return decimal2Scale(number, 2, digit);
    }

    /**
     * 十进制转其他进制
     *
     * @param number
     * @param scale
     * @return
     */
    public static String decimal2Scale(int number, int scale, int digit) {
        if (2 > scale || scale > 32) {
            throw new IllegalArgumentException("scale is not in range");
        }
        String result = "";
        while (0 != number) {
            result = number % scale + result;
            number = number / scale;
        }
        if (result.length() < digit) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < digit - result.length(); i++) {//给不足digit位的补0
                sb.append("0");
            }
            sb.append(result);
            result = sb.toString();
        }
        return result;
    }

    public static void checkNumber(String number) {
        String regexp = "^\\d+$";
        if (null == number || !number.matches(regexp)) {
            throw new IllegalArgumentException("input is not a number");
        }
    }

    public static int getInt(byte[] arr) {
        return (0xff000000 & (arr[0] << 24)) |
                (0xff000000 & (arr[1] << 16)) |
                (0xff000000 & (arr[2] << 8)) |
                (0xff000000 & (arr[3]));

    }

    public static float getFloat(byte[] arr) {
        return Float.intBitsToFloat(getInt(arr));
    }

    public static void main(String[] args) {
        // 6A 26
        System.out.println(NumberUtil.mergeByte2Hex((byte) 0x28, (byte) 0x74));

        // 0xD2, 0x5D, 0x38, 0x40
        byte[] b = new byte[]{(byte) 0xD2, (byte) 0x5D, (byte) 0x38, (byte) 0x40};
        System.out.println(getFloat(Arrays.copyOfRange(b, 0, 4)));
        b = new byte[]{(byte) 0x38, (byte) 0x40, (byte) 0xD2, (byte) 0x5D};
        System.out.println(getFloat(Arrays.copyOfRange(b, 0, 4)));
//        b = new byte[]{(byte) 0x5D, (byte) 0xD2, (byte) 0x40, (byte) 0x38};
//        System.out.println(getFloat(Arrays.copyOfRange(b, 0, 4)));
//        b = new byte[]{ (byte) 0x40, (byte) 0x38, (byte) 0x5D, (byte) 0xD2};
//        System.out.println(getFloat(Arrays.copyOfRange(b, 0, 4)));

    }
}